package com.xz.supplierContract.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.common.core.domain.model.LoginUser;
import com.xz.common.exception.ServiceException;
import com.xz.common.utils.DateUtils;
import com.xz.common.utils.SecurityUtils;
import com.xz.supplier.mapper.SupplierMapper;
import com.xz.supplierContract.domain.SupplierContract;
import com.xz.supplierContract.domain.SupplierContractAttachments;
import com.xz.supplierContract.domain.SupplierContractPriceScheme;
import com.xz.supplierContract.dto.SupplierContractDto;
import com.xz.supplierContract.mapper.SupplierContractMapper;
import com.xz.supplierContract.service.ISupplierContractAttachmentsService;
import com.xz.supplierContract.service.ISupplierContractPriceSchemeService;
import com.xz.supplierContract.service.ISupplierContractService;
import com.xz.supplierContract.vo.SupplierContractDetailVo;
import com.xz.supplierContract.vo.SupplierContractVo;
import common.ECDateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 合同Service业务层处理
 *
 * @author xz
 * @date 2024-02-26
 */
@Service
public class SupplierContractServiceImpl extends ServiceImpl<SupplierContractMapper, SupplierContract> implements ISupplierContractService {
  @Autowired
  private SupplierMapper supplierMapper;
  @Autowired
  private SupplierContractMapper supplierContractMapper;
  @Autowired
  private ISupplierContractAttachmentsService supplierContractAttachmentsService;
  @Autowired
  private ISupplierContractPriceSchemeService supplierContractPriceSchemeService;

  /**
   * 查询合同
   *
   * @param id 合同主键
   * @return 合同
   */
  @Override
  public SupplierContractDetailVo selectSupplierContractVoById(Long id) {
    SupplierContractDetailVo vo = supplierContractMapper.selectSupplierContractVoById(id);
    if (null != vo) {
      vo.setAttachmentsList(supplierContractAttachmentsService.selectByContractId(id));
      vo.setSchemeList(supplierContractPriceSchemeService.selectByContractId(id));
      //逾期数据处理
      vo.setContractStatus(updateStatusByDaysRemaining(vo.getId(), vo.getContractDayDiff(), vo.getContractStatus()));
    }
    return vo;
  }

  /**
   * 查询贸易供应商当下合同
   *
   * @param supplierId 贸易中间商主键
   * @return 合同
   */
  @Override
  public SupplierContract selectCurrentBySupplierId(Long supplierId) {
    if(null == supplierId){
      return null;
    }
    LambdaQueryWrapper<SupplierContract> wrapper = Wrappers.lambdaQuery(SupplierContract.class);
    Date currentDate = null;
    try {
      currentDate = ECDateUtils.getCurrentDate();
    } catch (ParseException e) {
      e.printStackTrace();
    }
    wrapper.eq(SupplierContract::getSupplierId, supplierId);
    //wrapper.le(null != currentDate,SupplierContract::getContractStartTime, currentDate);
    //wrapper.ge(null != currentDate,SupplierContract::getContractEndTime, ECDateUtils.getDateAfter(currentDate,1));
    List<Integer> stauts = new ArrayList();
    stauts.add(2);
    stauts.add(3);
    wrapper.in(SupplierContract::getContractStatus, stauts);
    wrapper.orderByDesc(SupplierContract::getCreateTime);

    List<SupplierContract> contracts = list(wrapper);
    SupplierContract contract = CollectionUtils.isEmpty(contracts) ? null : contracts.get(0);

    if(null != contract){
      //判断当前相同的日期是否在合同期限内
      Date date = null;
      try {
        date = ECDateUtils.getCurrentDateStartTime();
        boolean isAfterStartDate = contract.getContractStartTime().getTime() <= date.getTime();
        boolean isBeforeEndDate = contract.getContractEndTime().getTime() > date.getTime();
        // 如果在则说明需要采用合同价
        if(isAfterStartDate && isBeforeEndDate){
          contract.setAdoptingContractPrice(true);
        }else{
          contract.setAdoptingContractPrice(false);
        }
      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
    return contract;
  }

  /**
   * 查询合同列表
   *
   * @param supplierContract 合同
   * @return 合同
   */
  @Override
  public List<SupplierContractVo> selectSupplierContractVoList(SupplierContract supplierContract) {
    try {
      supplierContract.setCurrentDate(ECDateUtils.getCurrentDate());
    } catch (ParseException e) {
      e.printStackTrace();
    }
    List<SupplierContractVo> supplierContractVos = supplierContractMapper.selectSupplierContractVoList(supplierContract);
    if(!CollectionUtils.isEmpty(supplierContractVos)){
      supplierContractVos.forEach(vo->{
        //逾期数据处理
        vo.setContractStatus(updateStatusByDaysRemaining(vo.getId(), vo.getContractDayDiff(), vo.getContractStatus()));
      });
    }
    return supplierContractVos;
  }

  /**
   * 更新合同状态
   *
   * @param contractId 合同ID
   * @param daysRemaining 剩余天数
   * @return contractStatus 合同状态
   */
  private Integer updateStatusByDaysRemaining(Long contractId, Integer daysRemaining, Integer contractStatus) {
    if (daysRemaining <= 0 && contractStatus.intValue() == 2) {
      LambdaUpdateWrapper<SupplierContract> wrapper = Wrappers.lambdaUpdate(SupplierContract.class);
      wrapper.set(SupplierContract::getContractStatus, 3);
      wrapper.set(SupplierContract::getUpdateBy, SecurityUtils.getLoginUser().getUserId());
      wrapper.set(SupplierContract::getUpdateTime, DateUtils.getNowDate());
      wrapper.eq(SupplierContract::getId, contractId);
      return update(wrapper) ? 3 : contractStatus;
    }
    return contractStatus;
  }

  /**
   * 修改状态
   *
   * @param contractId 合同ID
   * @return contractStatus 合同状态
   */
  @Override
  public boolean editStatus(Long contractId, Integer contractStatus) {
    LambdaUpdateWrapper<SupplierContract> wrapper = Wrappers.lambdaUpdate(SupplierContract.class);
    wrapper.set(SupplierContract::getContractStatus, contractStatus);
    wrapper.set(SupplierContract::getUpdateBy, SecurityUtils.getLoginUser().getUserId());
    wrapper.set(SupplierContract::getUpdateTime, DateUtils.getNowDate());
    wrapper.eq(SupplierContract::getId, contractId);
    return update(wrapper);
  }

  /**
   * 新增合同
   *
   * @param dto 合同
   * @return 结果
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public int insertSupplierContract(SupplierContractDto dto) {
    // 校验合同id是否重复
    checkContractNo( dto);
    // 新增合同
    SupplierContract supplierContract = new SupplierContract();
    supplierContract.setContractStartTime(dto.getContractStartTime());
    supplierContract.setContractEndTime(dto.getContractEndTime());
    supplierContract.setContractNo(dto.getContractNo());
    supplierContract.setContractStatus(dto.getContractStatus());
    supplierContract.setRemark(dto.getRemark());
    supplierContract.setSupplierId(dto.getSupplierId());
    LoginUser user = SecurityUtils.getLoginUser();
    supplierContract.setCreateBy(user.getUserId());
    supplierContract.setCreateTime(DateUtils.getNowDate());
    supplierContract.setTenantId(user.getTenantId());
    supplierContract.setDeptId(user.getDeptId());
    supplierContract.setContractAttachmentsCount(dto.getAttachmentsListSize());
    supplierContract.setContractPriceSchemeCount(dto.getSchemeListSize());
    if(2 == dto.getContractStatus().intValue()){
      supplierContract.setSubmitTime(DateUtils.getNowDate());
    }
    int flag = supplierContractMapper.insertSupplierContract(supplierContract);
    if (flag > 0) {
      // 新增合同附件
      supplierContractAttachmentsService.insertForContract(supplierContract.getId(), supplierContract.getContractNo(), dto.getAttachmentsList());
      // 新增合同价格方案
      supplierContractPriceSchemeService.insertForContract(supplierContract, dto.getSchemeList());
    }
    return flag;
  }

  /**
   * 修改合同
   *
   * @param dto 合同
   * @return 结果
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public int updateSupplierContract(SupplierContractDto dto) {
    // 校验合同id是否重复
    checkContractNo( dto);
    // 更新合同
    SupplierContract supplierContract = getById(dto.getId());
    supplierContract.setContractNo(dto.getContractNo());
    supplierContract.setContractStartTime(dto.getContractStartTime());
    supplierContract.setContractEndTime(dto.getContractEndTime());
    supplierContract.setContractStatus(dto.getContractStatus());
    supplierContract.setSupplierId(dto.getSupplierId());
    supplierContract.setRemark(dto.getRemark());
    LoginUser user = SecurityUtils.getLoginUser();
    supplierContract.setUpdateBy(user.getUserId());
    supplierContract.setUpdateTime(DateUtils.getNowDate());
    supplierContract.setContractAttachmentsCount(dto.getAttachmentsListSize());
    supplierContract.setContractPriceSchemeCount(dto.getSchemeListSize());
    if(2 == dto.getContractStatus().intValue()){
      supplierContract.setSubmitTime(DateUtils.getNowDate());
    }
    int flag = supplierContractMapper.updateSupplierContract(supplierContract);
    if (flag > 0) {
      //更新合同附件
      supplierContractAttachmentsService.updateForContract(supplierContract.getId(), supplierContract.getContractNo(), dto.getAttachmentsList());
      //更新合同价格方案
      supplierContractPriceSchemeService.updateForContract(supplierContract, dto.getSchemeList());
    }
    return flag;
  }


  /**
   * 校验合同id是否重复
   * @param dto
   */
  private void checkContractNo(SupplierContractDto dto) {
    LambdaQueryWrapper<SupplierContract> wrapper = Wrappers.lambdaQuery(SupplierContract.class);
    wrapper.eq(SupplierContract::getContractNo, dto.getContractNo());
    wrapper.ne(null != dto.getId(),SupplierContract::getId, dto.getId());
    int count = this.count(wrapper);
    if(0 < count){
      throw new ServiceException("合同编号已存在，请输入其他合同编号");
    }
  }

  /**
   * 批量删除合同
   *
   * @param ids 需要删除的合同主键
   * @return 结果
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public boolean deleteSupplierContractByIds(Long[] ids) {
    //删除合同
    boolean flag = update(
      Wrappers.lambdaUpdate(SupplierContract.class)
        .set(SupplierContract::getDelFlag,2)
        .in(SupplierContract::getId,ids)
    );
    if(flag){
      //删除关联的附件
      supplierContractAttachmentsService.update(
        Wrappers.lambdaUpdate(SupplierContractAttachments.class)
          .set(SupplierContractAttachments::getDelFlag,2)
          .in(SupplierContractAttachments::getContractId,ids)
      );
      //删除关联的价格方案
      supplierContractPriceSchemeService.update(
        Wrappers.lambdaUpdate(SupplierContractPriceScheme.class)
          .set(SupplierContractPriceScheme::getDelFlag,2)
          .in(SupplierContractPriceScheme::getContractId,ids)
      );
    }
    return flag;
  }

}
